import os,sys,time
import pygame
pygame.init()

from monster import *
from tile import *
from maP import *
from world import *
from sfx import *

basic_path = os.path.dirname(os.path.realpath('main.py')) #just get the execution path for resources
print(basic_path)
data_path = basic_path+os.sep+'DATA'+os.sep
print(data_path)

class screen():
	
	def __init__(self):
		
		display_info = pygame.display.Info()
		
		self.scale_up = min(display_info.current_w, display_info.current_h)
		
		self.screen = pygame.display.set_mode((self.scale_up,self.scale_up),pygame.FULLSCREEN)
	
	def draw_title(self):
		
		s = pygame.Surface((64,64))
		s.blit(gl.glist['title'],(0,0))
		
		s = pygame.transform.scale(s,(screen.scale_up,screen.scale_up))
		screen.screen.blit(s,(0,0))
		pygame.display.flip()
		
		run = True
		
		while run:
			u = ui.get_ui(blocked=True)
			if u == 'e' or u == 'x':
				run = False
	
	def draw_gameover(self,victory=False):
		
		s = pygame.Surface((64,64))
		s.fill((20,12,28))
		
		if victory == False:
			sfx.play_sound('loose')
			dead_string = self.draw_string('YOU ARE DEAD')
		else:
			sfx.play_sound('win')
			dead_string = self.draw_string('  VICTORY')
		s.blit(dead_string,(3,6))
		
		score_string = self.draw_string('SCORE '+str(player.score))
		s.blit(score_string,(13,38))
		
		s = pygame.transform.scale(s,(screen.scale_up,screen.scale_up))
		screen.screen.blit(s,(0,0))
		pygame.display.flip()
		
		run = True
		
		while run:
			u = ui.get_ui(True)
			if u == 'e' or u == 'x':
				run = False
		
		exit(0)
	
	def draw_brake(self):
		
		run = True
		num = 0
		
		while run:
			
			bg = screen.render(simulation=True)
			
			bg.blit(gl.glist['unknown_mage'],(player.y*8,player.x*8))
			
			bg.blit(gl.glist['box2'],(8,11))
			
			resume = self.draw_string('RESUME')
			
			bg.blit(resume,(17,13))
			
			last_cp = self.draw_string('LAST CP')
			
			bg.blit(last_cp,(17,21))
			
			exit_s = self.draw_string('EXIT')
			
			bg.blit(exit_s,(17,29))
			
			bg.blit(gl.glist['marker'],(9,12+(num*8)))
			
			s = pygame.transform.scale(bg,(screen.scale_up,screen.scale_up))
			screen.screen.blit(s,(0,0))
			pygame.display.flip()
			
			u_input = ui.get_ui(False,True)
			
			if u_input == 'w':
				num -= 1
				sfx.play_sound('beep')
				if num < 0:
					num = 2
			
			if u_input == 's':
				num += 1
				sfx.play_sound('beep')
				if num > 2:
					num = 0
					
			if u_input == 'e':
				if num == 0:
					run = False
				elif num == 1:
					sfx.play_sound('tp')
					player.on_map = player.last_cp_map
					player.x = player.last_cp_x
					player.y = player.last_cp_y
					player.x_dest = player.x
					player.y_dest = player.y
					run = False
				else:
					exit(0)
					
	
	def draw_map(self,re_maP):
		
		s = pygame.Surface((64,64))
		
		for y in range(0,8):
			for x in range(0,8):
				s.blit(gl.glist[tile_list[re_maP.tiles[y][x]].graphic],(x*8,y*8))
				
		return s
	
	def draw_string(self,string):
		
		l = len(string)
		
		s = pygame.Surface((l*8,5))
		s.fill((255,0,255))
		
		for i in range(0,l):
			if string[i] != ' ':
				s.blit(gl.glist[string[i]],(5*i,0))
		
		s.set_colorkey((255,0,255),pygame.RLEACCEL)
		s = s.convert_alpha()
			
		return s
		
	def draw_lp(self):
		
		s = pygame.Surface((22,4))
		s.blit(gl.glist['lp_bar_empty'],(0,0))
		
		help_s = pygame.Surface((max(player.lp*2,0),4))
		help_s.blit(gl.glist['lp_bar_full'],(0,0))
		
		s.blit(help_s,(1,0))
		
		return s
		
	def draw_monster(self,monster):
		
		s = pygame.Surface((8,8))
		s.fill((255,0,255))
		if monster.lp > 0:
			s.blit(gl.glist[monster.graphic],(0,0))
		
		#if monster.lp >= 3:
		#	s.blit(gl.glist['mon_3_lp'],(0,0))
		#elif monster.lp == 2:
		#	s.blit(gl.glist['mon_2_lp'],(0,0))
		#elif monster.lp == 1:
		#	s.blit(gl.glist['mon_1_lp'],(0,0))
		if monster.lp < 1:
			s.blit(gl.glist['monster_dead'],(0,0))
			
		s.set_colorkey((255,0,255),pygame.RLEACCEL)
		s = s.convert_alpha()
			
		return s
	
	def render(self,blink='none',simulation=False):
		
		map_image = self.draw_map(world[player.on_map])
		
		for c in range(0,8):
			offset.set_offset(c)
			
			if player.x_dest > player.x:
				y_offset = offset.h_y_offset
				x_offset = offset.h_x_offset
			elif player.x_dest < player.x:
				y_offset = offset.h_y_offset
				x_offset = offset.h_x_offset*(-1)
			elif player.y_dest > player.y:
				y_offset = offset.v_y_offset
				x_offset = offset.v_x_offset
			elif player.y_dest < player.y:
				y_offset = offset.v_y_offset*(-1)
				x_offset = offset.v_x_offset
			else:
				x_offset = 0
				y_offset = 0
				
			s = pygame.Surface((64,64))
			s.blit(map_image,(0,0))
			
			for i in world[player.on_map].monsters:
				if i.x_dest > i.x:
					m_y_offset = offset.h_y_offset
					m_x_offset = offset.h_x_offset
				elif i.x_dest < i.x:
					m_y_offset = offset.h_y_offset
					m_x_offset = offset.h_x_offset*(-1)
				elif i.y_dest > i.y:
					m_y_offset = offset.v_y_offset
					m_x_offset = offset.v_x_offset
				elif i.y_dest < i.y:
					m_y_offset = offset.v_y_offset*(-1)
					m_x_offset = offset.v_x_offset
				else:
					m_x_offset = 0
					m_y_offset = 0
				
				s.blit(self.draw_monster(i),((i.y*8)+m_y_offset,(i.x*8)+m_x_offset))
			
			s.blit(gl.glist['player'][player.mage],((player.y*8)+y_offset,(player.x*8)+x_offset))
			
			if blink != 'none':
				alpha = (32,64,128,128,255,128,128,64,32)
				color = {'red' : (208,70,72,alpha[c]) , 'white' : (222,238,214,alpha[c]) , 'blue' : (133,149,161,alpha[c])}
				
				bs = pygame.Surface((64,64),pygame.SRCALPHA)
				bs.fill(color[blink])
				s.blit(bs,(0,0))
			
			s.blit(screen.draw_lp(),(0,0))
			s.blit(gl.glist['key_w'],(23,0))
			
			if len(str(player.keys)) == 2:
				key_string = str(player.keys)
			else:
				key_string = '0'+str(player.keys)
			
			s.blit(screen.draw_string(key_string),(29,0))	
			
			sn = 4-len(str(player.score))
			zero_string = ''
			if sn > 0:
				for j in range(0,sn):
					zero_string += '0'
					
			score_string = zero_string + str(player.score)
			
			s.blit(screen.draw_string(score_string),(45,0))
			
			if simulation == True:
				return s
			
			s = pygame.transform.scale(s,(self.scale_up,self.scale_up))
			self.screen.blit(s,(0,0))
			pygame.display.flip()
			clock.tick(24)

class offset():
	
	def __init__(self):
		
		self.h_x_offset = 0
		self.h_y_offset = 0
		self.v_x_offset = 0
		self.v_y_offset = 0
		
	def set_offset(self,frame):
		
		self.v_y_offset = frame
		self.h_x_offset = frame
		
		if frame % 4 == 0:
			if self.v_y_offset == 0: 
				self.v_x_offset = -1
				self.h_y_offset = -1
			else:
				self.v_x_offset = 0
				self.h_y_offset = 0

class gra_files():
	
	def __init__(self):
		
		self.glist = {}
		
		self.glist['player'] = []
		
		i_name = data_path + 'firemage.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['player'].append(i)
		
		i_name = data_path + 'watermage.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['player'].append(i)
		
		i_name = data_path + 'skymage.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['player'].append(i)
		
		i_name = data_path + 'earthmage.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['player'].append(i)
		
		#Alphabet
		al = ('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9','0','+','-')
		
		for j in al:
			i_name = data_path + j +'.png'
			i = pygame.image.load(i_name)
			i.set_colorkey((255,0,255),pygame.RLEACCEL)
			i = i.convert_alpha()
			self.glist[j] = i
			
		#/Alphabet
		
		i_name = data_path + 'earth.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['earth'] = i
		
		i_name = data_path + 'fire.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['fire'] = i
		
		i_name = data_path + 'water.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['water'] = i
		
		i_name = data_path + 'air.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['air'] = i
		
		i_name = data_path + 'lp_bar_full.png'
		i = pygame.image.load(i_name)
		self.glist['lp_bar_full'] = i
		
		i_name = data_path + 'lp_bar_empty.png'
		i = pygame.image.load(i_name)
		self.glist['lp_bar_empty'] = i
		
		i_name = data_path + 'lp_bar_blink.png'
		i = pygame.image.load(i_name)
		self.glist['lp_bar_blink'] = i
		
		i_name = data_path + 'title.png'
		i = pygame.image.load(i_name)
		self.glist['title'] = i
		
		i_name = data_path + 'wall.png'
		i = pygame.image.load(i_name)
		self.glist['wall'] = i
		
		i_name = data_path + 'floor.png'
		i = pygame.image.load(i_name)
		self.glist['floor'] = i
		
		i_name = data_path + 'fence.png'
		i = pygame.image.load(i_name)
		self.glist['fence'] = i
		
		i_name = data_path + 'heart.png'
		i = pygame.image.load(i_name)
		self.glist['heart'] = i
		
		i_name = data_path + 'door.png'
		i = pygame.image.load(i_name)
		self.glist['door'] = i
		
		i_name = data_path + 'key.png'
		i = pygame.image.load(i_name)
		self.glist['key'] = i
		
		i_name = data_path + 'thorn.png'
		i = pygame.image.load(i_name)
		self.glist['thorn'] = i
		
		i_name = data_path + 'gem.png'
		i = pygame.image.load(i_name)
		self.glist['gem'] = i
		
		i_name = data_path + 'checkpoint_activ.png'
		i = pygame.image.load(i_name)
		self.glist['checkpoint_activ'] = i
		
		i_name = data_path + 'checkpoint_passiv.png'
		i = pygame.image.load(i_name)
		self.glist['checkpoint_passiv'] = i
		
		i_name = data_path + 'amulett.png'
		i = pygame.image.load(i_name)
		self.glist['amulett'] = i
		
		i_name = data_path + 'teleport.png'
		i = pygame.image.load(i_name)
		self.glist['teleport'] = i
		
		i_name = data_path + 'unknown_mage.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['unknown_mage'] = i
		
		i_name = data_path + 'box1.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['box1'] = i
		
		i_name = data_path + 'box2.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['box2'] = i
		
		i_name = data_path + 'marker.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['marker'] = i
		
		i_name = data_path + 'key_w.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['key_w'] = i
		
		i_name = data_path + 'mon_3_lp.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['mon_3_lp'] = i
		
		i_name = data_path + 'mon_2_lp.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['mon_2_lp'] = i
		
		i_name = data_path + 'mon_1_lp.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['mon_1_lp'] = i
		
		i_name = data_path + 'monster_dead.png'
		i = pygame.image.load(i_name)
		i.set_colorkey((255,0,255),pygame.RLEACCEL)
		i = i.convert_alpha()
		self.glist['monster_dead'] = i


class player():
	
	def __init__(self):
		
		self.x = 4
		self.y = 4
		
		self.x_dest = self.x
		self.y_dest = self.y
		
		self.on_map = 'map1'
		
		self.last_cp_map = self.on_map
		self.last_cp_x = self.x
		self.last_cp_y = self.y
		
		self.mage = 0
		
		self.lp_max = 10
		self.lp = self.lp_max
		
		self.keys = 0
		
		self.score = 0
		
		self.move_blocked = False
		
	def check_wall_col(self,te_maP,x,y):
		
		global blink
		
		if x != player.x:
			x_change = True
		else:
			x_change = False
		
		if x_change == True and player.y_dest != player.y:
			player.y_dest = player.y
		elif x_change == False and player.x_dest != player.x:
			player.x_dest = player.x
		
		if self.move_blocked == True:
			return False
		
		if min(x,y) > -1 and max(x,y) < 8:
			
			for i in range(0,len(te_maP.monsters)):
				if x == te_maP.monsters[i].x and y == te_maP.monsters[i].y and te_maP.monsters[i].move_blocked == False:
					blink = te_maP.monsters[i].fight(self,te_maP)
				elif x == te_maP.monsters[i].x and y == te_maP.monsters[i].y:
					return False
			
			if world[self.on_map].tiles[x][y] == 'A':
				screen.draw_gameover(True)
			
			if world[self.on_map].tiles[x][y] == 't':
				sfx.play_sound('tp')
			
			if tile_list[te_maP.tiles[x][y]].special == 'cp_passiv':
				world[self.on_map].tiles[x][y] = 'C'
				world[self.last_cp_map].tiles[self.last_cp_x][self.last_cp_y] = 'c'
				self.last_cp_map = player.on_map
				self.last_cp_x = x
				self.last_cp_y = y
				sfx.play_sound('activate')
				blink = 'white'
			
			if tile_list[te_maP.tiles[x][y]].hurt:
				self.lp -= 1
				sfx.play_sound('hit')
				blink = 'red'
			
			if tile_list[te_maP.tiles[x][y]].special == 'key':
				world[self.on_map].tiles[x][y] = '.'
				self.keys += 1
				sfx.play_sound('got')
				blink = 'white'
			
			if tile_list[te_maP.tiles[x][y]].special == 'heart':
				world[self.on_map].tiles[x][y] = '.'
				self.lp = self.lp_max
				sfx.play_sound('heal')
				blink = 'white'
			
			if tile_list[te_maP.tiles[x][y]].special == 'gem':
				world[self.on_map].tiles[x][y] = '.'
				self.score += 10
				sfx.play_sound('got')
				blink = 'blue'
				
			if tile_list[te_maP.tiles[x][y]].special == 'door' and self.keys > 0:
				world[self.on_map].tiles[x][y] = '.'
				self.keys -= 1
				sfx.play_sound('door')
				return False
			
			if tile_list[te_maP.tiles[x][y]].move == True:
				if pygame.mixer.get_busy() == False:
					sfx.play_sound('step')
			
			return tile_list[te_maP.tiles[x][y]].move
		else:
			return False
	
	def check_tp(self,te_maP):
		
		for i in te_maP.tp:
			if self.x == i[0] and self.y == i[1]:
				self.on_map = i[2]
				self.x = i[3]
				self.y = i[4]
				self.x_dest = self.x
				self.y_dest = self.y
				
				return True
		
		return False
		
	def choose_mage(self):
		
		run = True
		num = 0
		
		while run:
			
			bg = screen.render(simulation=True)
			
			bg.blit(gl.glist['unknown_mage'],(player.y*8,player.x*8))
			
			bg.blit(gl.glist['box1'],(23,13))
			
			for i in range(0,4):
				bg.blit(gl.glist['player'][i],(33,15+(i*9)))
				
			bg.blit(gl.glist['marker'],(25,15+(num*9)))
			
			s = pygame.transform.scale(bg,(screen.scale_up,screen.scale_up))
			screen.screen.blit(s,(0,0))
			pygame.display.flip()
			
			u_input = ui.get_ui(False,True)
			
			if u_input == 'w':
				num -= 1
				sfx.play_sound('beep')
				if num < 0:
					num = 3
			elif u_input == 's':
				num += 1
				sfx.play_sound('beep')
				if num > 3:
					num = 0
			elif u_input == 'e':
				return num
			elif u_input == 'x':
				run = False
				return self.mage
		
class ui():
	
	def __init__(self):
		
		self.vcon ={'w':False,'s':False,'a':False,'d':False,'e':False,'x':False}
		self.num_blocked = 0
			
	def get_ui(self,blocked,one_press=False):
		
			if one_press == True:
				self.vcon ={'w':False,'s':False,'a':False,'d':False,'e':False,'x':False}
		
			g = None
			
			if blocked == True:
				self.num_blocked += 1
				if self.num_blocked > 2:
					blocked = False
			else:
				self.num_blocked = 0
		
			for event in pygame.event.get():
				if event.type == pygame.KEYDOWN:
					if (event.key == pygame.K_w or event.key == pygame.K_UP) and blocked == False:
						self.vcon['w'] = True
					elif (event.key == pygame.K_s or event.key == pygame.K_DOWN) and blocked == False:
						self.vcon['s'] = True
					elif (event.key == pygame.K_a or event.key == pygame.K_LEFT) and blocked == False:
						self.vcon['a'] = True
					elif (event.key == pygame.K_d or event.key == pygame.K_RIGHT) and blocked == False:
						self.vcon['d'] = True
					elif event.key == pygame.K_e or event.key == pygame.K_SPACE:
						self.vcon['e'] = True
					if event.key == pygame.K_x or event.key == pygame.K_ESCAPE:
						self.vcon['x'] = True
				elif event.type == pygame.KEYUP and one_press == False:
					if (event.key == pygame.K_w or event.key == pygame.K_UP):
						self.vcon['w'] = False
					elif (event.key == pygame.K_s or event.key == pygame.K_DOWN):
						self.vcon['s'] = False
					elif (event.key == pygame.K_a or event.key == pygame.K_LEFT):
						self.vcon['a'] = False
					elif (event.key == pygame.K_d or event.key == pygame.K_RIGHT):
						self.vcon['d'] = False
					elif event.key == pygame.K_e or event.key == pygame.K_SPACE:
						self.vcon['e'] = False
					if event.key == pygame.K_x or event.key == pygame.K_ESCAPE:
						self.vcon['x'] = False
			
			if self.vcon['w'] == True:
				g = 'w'
			elif self.vcon['s'] == True:
				g = 's'
			elif self.vcon['a'] == True:
				g = 'a'
			elif self.vcon['d'] == True:
				g = 'd'
			elif self.vcon['e'] == True:
				g = 'e'
			if self.vcon['x'] == True:
				g = 'x'
						
			return g

screen = screen()
gl = gra_files()
ui = ui()
sfx = sfx(data_path)
offset = offset()
player = player()
clock = pygame.time.Clock()

screen.draw_title()

blink = 'none'

run = True

loop_count = 0

while run:
	
	player.check_tp(world[player.on_map])
	####test
	screen.render(blink)
	####/test
	
	if player.lp <= 0:
		screen.draw_gameover()
	
	blink = 'none'
	user_input = ui.get_ui(player.move_blocked)
	
	player.move_blocked = False
	
	player.x = player.x_dest
	player.y = player.y_dest
	
	if user_input == 'x':
		screen.draw_brake()
		
	if user_input == 'w':
		if player.check_wall_col(world[player.on_map],player.x-1,player.y):
			player.x_dest -=1
	
	if user_input == 's':
		if player.check_wall_col(world[player.on_map],player.x+1,player.y):
			player.x_dest +=1
		
	if user_input == 'a':
		if player.check_wall_col(world[player.on_map],player.x,player.y-1):
			player.y_dest -=1
	
	if user_input == 'd':
		if player.check_wall_col(world[player.on_map],player.x,player.y+1):
			player.y_dest +=1

	if user_input == 'e' and world[player.on_map].tiles[player.x][player.y] == 'C':
		player.mage = player.choose_mage()
	
	ml = []
	
	for k in range(0,len(world[player.on_map].monsters)):
		if world[player.on_map].monsters[k].lp > 0:
			ml.append(world[player.on_map].monsters[k])
	
	world[player.on_map].monsters = ml		
		
	for q in range(0,len(world[player.on_map].monsters)):
	
		if world[player.on_map].monsters[q].move_blocked == False:
			b_test = world[player.on_map].monsters[q].AI_move(player,world[player.on_map])
		else:
			b_test = None
			
		if b_test == 'red' or b_test == 'blue' or b_test == 'white':
			blink = b_test
		world[player.on_map].monsters[q].move_blocked = False
